package com.ssy.lingxi.member.merchant.serviceimpl.web;

import cn.hutool.core.util.StrUtil;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.ssy.lingxi.common.constant.CommonConstant;
import com.ssy.lingxi.common.constant.basic.EnableDisableStatus;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.member.merchant.entity.*;
import com.ssy.lingxi.member.merchant.model.vo.lifecycle.request.CommonIdVO;
import com.ssy.lingxi.member.merchant.model.vo.maintenance.request.*;
import com.ssy.lingxi.member.merchant.model.vo.maintenance.response.*;
import com.ssy.lingxi.member.merchant.repository.MemberOrganizationRepository;
import com.ssy.lingxi.member.merchant.repository.MemberRepository;
import com.ssy.lingxi.member.merchant.repository.MemberStoreRepository;
import com.ssy.lingxi.member.merchant.service.base.IBaseMemberCacheService;
import com.ssy.lingxi.member.merchant.service.base.IBaseMemberOrganizationService;
import com.ssy.lingxi.member.merchant.service.queue.ILogisticsMessageQueueService;
import com.ssy.lingxi.member.merchant.service.web.IMemberAbilityStoreService;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * 系统能力 - 权限管理 - 门店管理服务接口实现类
 * @author wyx
 * @version 2.0.0
 * @date 2022/02/10
 */
@Service
public class MemberAbilityStoreServiceImpl implements IMemberAbilityStoreService {

    @Resource
    private IBaseMemberCacheService memberCacheService;
    @Resource
    private MemberStoreRepository memberStoreRepository;
    @Resource
    private MemberRepository memberRepository;
    @Resource
    private IBaseMemberOrganizationService baseMemberOrganizationService;
    @Resource
    private MemberOrganizationRepository memberOrganizationRepository;
    @Resource
    private JPAQueryFactory jpaQueryFactory;
    @Resource
    private ILogisticsMessageQueueService logisticsMessageQueueService;


    /**
     * 门店管理分页查询列表
     * @param headers HttpHeaders信息
     * @param pageVO  接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MemberStorePageQueryVO>> memberStorePages(HttpHeaders headers, MemberStorePageVO pageVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);

        //表实体
        QMemberStoreDO qMemberStoreDO = QMemberStoreDO.memberStoreDO;
        QMemberOrganizationDO qMemberOrganizationDO = QMemberOrganizationDO.memberOrganizationDO;
        //构造查询条件
        BooleanBuilder predicates = new BooleanBuilder();
        predicates.and(qMemberStoreDO.member.id.eq(loginUser.getMemberId()));

        if (StrUtil.isNotEmpty(pageVO.getName())) {
            predicates.and(qMemberStoreDO.name.like(("%" + pageVO.getName() + "%")));
        }
        if (StrUtil.isNotEmpty(pageVO.getContactName())) {
            predicates.and(qMemberStoreDO.contactName.like(("%" + pageVO.getContactName() + "%")));
        }
        if (pageVO.getStatus() != null) {
            predicates.and(qMemberStoreDO.status.eq(pageVO.getStatus()));
        }

        JPAQuery<MemberStorePageQueryVO> query = jpaQueryFactory
                .selectDistinct(Projections.constructor(MemberStorePageQueryVO.class,
                        qMemberStoreDO.id,
                        qMemberStoreDO.code,
                        qMemberStoreDO.name,
                        qMemberStoreDO.provinceName,
                        qMemberStoreDO.cityName,
                        qMemberStoreDO.districtName,
                        qMemberStoreDO.streetName,
                        qMemberStoreDO.address,
                        qMemberStoreDO.postalCode,
                        qMemberStoreDO.contactName,
                        qMemberStoreDO.countryCode,
                        qMemberOrganizationDO.title,
                        qMemberStoreDO.phone,
                        qMemberStoreDO.status))
                .from(qMemberStoreDO)
                .leftJoin(qMemberOrganizationDO).on(qMemberStoreDO.org.id.eq(qMemberOrganizationDO.id))
                .where(predicates);

        //总记录数
        long totalCount = query.fetchCount();

        List<MemberStorePageQueryVO> storeList = query.orderBy(qMemberStoreDO.id.asc()).offset(pageVO.getCurrentOffset()).limit(pageVO.getPageSize()).fetch();

        return Wrapper.success(new PageData<>(totalCount, storeList));
    }

    /**
     * 查看门店详情
     * @param headers HttpHeaders信息
     * @param idVO    接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberStoreDetailVO> memberStoreDetail(HttpHeaders headers, CommonIdVO idVO) {
        memberCacheService.needLoginFromBusinessPlatform(headers);

        MemberStoreDO memberStoreDO = memberStoreRepository.findById(idVO.getId()).orElse(null);
        if (memberStoreDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_STORE_DOES_NOT_EXIST);
        }

        //门店详情
        MemberStoreDetailVO detailVO = new MemberStoreDetailVO(memberStoreDO);
        //所属组积机构
        MemberOrganizationVO organizationVO = new MemberOrganizationVO(memberStoreDO.getOrg());
        detailVO.setOrg(organizationVO);
        //发货地址
        MemberDeliverAddressDO deliverAddress = memberStoreDO.getDeliverAddress();
        detailVO.setDeliverAddress(deliverAddress == null ? null : new MemberDeliverAddressDetailVO(deliverAddress));
        //收货地址
        MemberReceiveAddressDO receiveAddress = memberStoreDO.getReceiveAddress();
        detailVO.setReceiveAddress(receiveAddress == null ? null : new MemberReceiveAddressDetailVO(receiveAddress));
        return Wrapper.success(detailVO);
    }

    /**
     * 新增门店
     * @param headers HttpHeaders信息
     * @param addVO   接口参数
     * @return 操作结果
     */
    @Override
    @Transactional(rollbackFor = BusinessException.class)
    public Wrapper<Void> addMemberStore(HttpHeaders headers, MemberStoreAddVO addVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);

        MemberDO memberDO = memberRepository.findById(loginUser.getMemberId()).orElse(null);
        if (memberDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_DOES_NOT_EXIST);
        }

        MemberStoreDO memberStoreDO = new MemberStoreDO();
        memberStoreDO.setMember(memberDO);
        memberStoreDO.setCode(addVO.getCode());
        memberStoreDO.setName(addVO.getName());
        memberStoreDO.setLogo(addVO.getLogo());
        memberStoreDO.setProvinceCode(addVO.getProvinceCode());
        memberStoreDO.setProvinceName(addVO.getProvinceName());
        memberStoreDO.setCityCode(addVO.getCityCode());
        memberStoreDO.setCityName(addVO.getCityName());
        memberStoreDO.setDistrictCode(addVO.getDistrictCode());
        memberStoreDO.setDistrictName(addVO.getDistrictName());
        memberStoreDO.setStreetCode(addVO.getStreetCode());
        memberStoreDO.setStreetName(addVO.getStreetName());
        memberStoreDO.setAddress(addVO.getAddress());
        memberStoreDO.setPostalCode(addVO.getPostalCode());
        memberStoreDO.setContactName(addVO.getContactName());
        memberStoreDO.setCountryCode(addVO.getCountryCode());
        memberStoreDO.setPhone(addVO.getPhone());
        memberStoreDO.setEmail(addVO.getEmail());
        memberStoreDO.setPosition(addVO.getPosition());
        memberStoreDO.setStatus(CommonConstant.State.STATE_START);

        //发货地址
        MemberDeliverAddressVO deliverAddressVO = addVO.getDeliverAddress();
        if (deliverAddressVO != null) {
            MemberDeliverAddressDO deliverAddressDO = new MemberDeliverAddressDO();
            deliverAddressDO.setDeliverName(deliverAddressVO.getDeliverName());
            deliverAddressDO.setProvinceCode(deliverAddressVO.getProvinceCode());
            deliverAddressDO.setProvinceName(deliverAddressVO.getProvinceName());
            deliverAddressDO.setCityCode(deliverAddressVO.getCityCode());
            deliverAddressDO.setCityName(deliverAddressVO.getCityName());
            deliverAddressDO.setDistrictCode(deliverAddressVO.getDistrictCode());
            deliverAddressDO.setDistrictName(deliverAddressVO.getDistrictName());
            deliverAddressDO.setStreetCode(deliverAddressVO.getStreetCode());
            deliverAddressDO.setStreetName(deliverAddressVO.getStreetName());
            deliverAddressDO.setAddress(deliverAddressVO.getAddress());
            deliverAddressDO.setPostalCode(deliverAddressVO.getPostalCode());
            deliverAddressDO.setAreaCode(deliverAddressVO.getAreaCode());
            deliverAddressDO.setPhone(deliverAddressVO.getPhone());
            deliverAddressDO.setTel(deliverAddressVO.getTel());
            deliverAddressDO.setIsDefault(deliverAddressVO.getIsDefault());

            memberStoreDO.setDeliverAddress(deliverAddressDO);
        }

        //收货地址
        MemberReceiveAddressVO receiveAddressVO = addVO.getReceiveAddress();
        if (receiveAddressVO != null) {
            MemberReceiveAddressDO receiveAddressDO = new MemberReceiveAddressDO();
            receiveAddressDO.setReceiverName(receiveAddressVO.getReceiverName());
            receiveAddressDO.setProvinceCode(receiveAddressVO.getProvinceCode());
            receiveAddressDO.setProvinceName(receiveAddressVO.getProvinceName());
            receiveAddressDO.setCityCode(receiveAddressVO.getCityCode());
            receiveAddressDO.setCityName(receiveAddressVO.getCityName());
            receiveAddressDO.setDistrictCode(receiveAddressVO.getDistrictCode());
            receiveAddressDO.setDistrictName(receiveAddressVO.getDistrictName());
            receiveAddressDO.setStreetCode(receiveAddressVO.getStreetCode());
            receiveAddressDO.setStreetName(receiveAddressVO.getStreetName());
            receiveAddressDO.setAddress(receiveAddressVO.getAddress());
            receiveAddressDO.setPostalCode(receiveAddressVO.getPostalCode());
            receiveAddressDO.setAreaCode(receiveAddressVO.getAreaCode());
            receiveAddressDO.setPhone(receiveAddressVO.getPhone());
            receiveAddressDO.setTel(receiveAddressVO.getTel());
            receiveAddressDO.setIsDefault(receiveAddressVO.getIsDefault());

            memberStoreDO.setReceiveAddress(receiveAddressDO);
        }

        MemberOrganizationDO organizationDO = memberOrganizationRepository.findById(addVO.getOrgId()).orElse(null);
        if (organizationDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_ORGANIZATION_DOES_NOT_EXIST);
        }
        //门店所属组积机构
        memberStoreDO.setOrg(organizationDO);

        //添加门店到所属组织机构
        baseMemberOrganizationService.addMemberStoreOrg(memberStoreDO, memberDO, addVO.getOrgId(), addVO.getName(), addVO.getCode());

        memberStoreRepository.saveAndFlush(memberStoreDO);

        //同步门店收发货地址数据到物流服务
        logisticsMessageQueueService.syncLogisticsAddress(memberStoreDO, loginUser, addVO.getDeliverAddress(), addVO.getReceiveAddress(), true);

        return Wrapper.success();
    }

    /**
     * 修改门店
     * @param headers  HttpHeaders信息
     * @param updateVO 接口参数
     * @return 操作结果
     */
    @Override
    @Transactional(rollbackFor = BusinessException.class)
    public Wrapper<Void> updateMemberStore(HttpHeaders headers, MemberStoreUpdateVO updateVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);

        MemberStoreDO memberStoreDO = memberStoreRepository.findById(updateVO.getId()).orElse(null);
        if (memberStoreDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_STORE_DOES_NOT_EXIST);
        }
        memberStoreDO.setCode(updateVO.getCode());
        memberStoreDO.setName(updateVO.getName());
        memberStoreDO.setLogo(updateVO.getLogo());
        memberStoreDO.setProvinceCode(updateVO.getProvinceCode());
        memberStoreDO.setProvinceName(updateVO.getProvinceName());
        memberStoreDO.setCityCode(updateVO.getCityCode());
        memberStoreDO.setCityName(updateVO.getCityName());
        memberStoreDO.setDistrictCode(updateVO.getDistrictCode());
        memberStoreDO.setDistrictName(updateVO.getDistrictName());
        memberStoreDO.setStreetCode(updateVO.getStreetCode());
        memberStoreDO.setStreetName(updateVO.getStreetName());
        memberStoreDO.setAddress(updateVO.getAddress());
        memberStoreDO.setPostalCode(updateVO.getPostalCode());
        memberStoreDO.setContactName(updateVO.getContactName());
        memberStoreDO.setCountryCode(updateVO.getCountryCode());
        memberStoreDO.setPhone(updateVO.getPhone());
        memberStoreDO.setEmail(updateVO.getEmail());
        memberStoreDO.setPosition(updateVO.getPosition());

        //发货地址
        MemberDeliverAddressVO deliverAddressVO = updateVO.getDeliverAddress();
        if (deliverAddressVO == null) {
            memberStoreDO.setDeliverAddress(null);
        } else {
            MemberDeliverAddressDO deliverAddressDO = memberStoreDO.getDeliverAddress();
            if (deliverAddressDO == null) {
                deliverAddressDO = new MemberDeliverAddressDO();
            }
            deliverAddressDO.setDeliverName(deliverAddressVO.getDeliverName());
            deliverAddressDO.setProvinceCode(deliverAddressVO.getProvinceCode());
            deliverAddressDO.setProvinceName(deliverAddressVO.getProvinceName());
            deliverAddressDO.setCityCode(deliverAddressVO.getCityCode());
            deliverAddressDO.setCityName(deliverAddressVO.getCityName());
            deliverAddressDO.setDistrictCode(deliverAddressVO.getDistrictCode());
            deliverAddressDO.setDistrictName(deliverAddressVO.getDistrictName());
            deliverAddressDO.setStreetCode(deliverAddressVO.getStreetCode());
            deliverAddressDO.setStreetName(deliverAddressVO.getStreetName());
            deliverAddressDO.setAddress(deliverAddressVO.getAddress());
            deliverAddressDO.setPostalCode(deliverAddressVO.getPostalCode());
            deliverAddressDO.setAreaCode(deliverAddressVO.getAreaCode());
            deliverAddressDO.setPhone(deliverAddressVO.getPhone());
            deliverAddressDO.setTel(deliverAddressVO.getTel());
            deliverAddressDO.setIsDefault(deliverAddressVO.getIsDefault());
            memberStoreDO.setDeliverAddress(deliverAddressDO);
        }

        //收货地址
        MemberReceiveAddressVO receiveAddressVO = updateVO.getReceiveAddress();
        if (receiveAddressVO == null) {
            memberStoreDO.setReceiveAddress(null);
        } else {
            MemberReceiveAddressDO receiveAddressDO = memberStoreDO.getReceiveAddress();
            if (receiveAddressDO == null) {
                receiveAddressDO = new MemberReceiveAddressDO();
            }
            receiveAddressDO.setReceiverName(receiveAddressVO.getReceiverName());
            receiveAddressDO.setProvinceCode(receiveAddressVO.getProvinceCode());
            receiveAddressDO.setProvinceName(receiveAddressVO.getProvinceName());
            receiveAddressDO.setCityCode(receiveAddressVO.getCityCode());
            receiveAddressDO.setCityName(receiveAddressVO.getCityName());
            receiveAddressDO.setDistrictCode(receiveAddressVO.getDistrictCode());
            receiveAddressDO.setDistrictName(receiveAddressVO.getDistrictName());
            receiveAddressDO.setStreetCode(receiveAddressVO.getStreetCode());
            receiveAddressDO.setStreetName(receiveAddressVO.getStreetName());
            receiveAddressDO.setAddress(receiveAddressVO.getAddress());
            receiveAddressDO.setPostalCode(receiveAddressVO.getPostalCode());
            receiveAddressDO.setAreaCode(receiveAddressVO.getAreaCode());
            receiveAddressDO.setPhone(receiveAddressVO.getPhone());
            receiveAddressDO.setTel(receiveAddressVO.getTel());
            receiveAddressDO.setIsDefault(receiveAddressVO.getIsDefault());
            memberStoreDO.setReceiveAddress(receiveAddressDO);
        }

        MemberOrganizationDO organizationDO = memberOrganizationRepository.findById(updateVO.getOrgId()).orElse(null);
        if (organizationDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_ORGANIZATION_DOES_NOT_EXIST);
        }
        //所属组积机构
        memberStoreDO.setOrg(organizationDO);

        memberStoreRepository.saveAndFlush(memberStoreDO);

        //更新组织机构名称
        MemberOrganizationDO memberOrganizationDO = memberOrganizationRepository.findFirstByMemberIdAndStoreId(loginUser.getMemberId(), memberStoreDO.getId());
        if (memberOrganizationDO != null) {
            memberOrganizationDO.setCode(updateVO.getCode());
            memberOrganizationDO.setTitle(updateVO.getName());
            memberOrganizationDO.setParentId(updateVO.getOrgId());
            memberOrganizationDO.setLevel(organizationDO.getLevel() + 1);
            memberOrganizationRepository.saveAndFlush(memberOrganizationDO);
        }

        //同步门店收发货地址数据到物流服务
        logisticsMessageQueueService.syncLogisticsAddress(memberStoreDO, loginUser, updateVO.getDeliverAddress(), updateVO.getReceiveAddress(), false);

        return Wrapper.success();
    }

    /**
     * 删除门店
     * @param headers HttpHeaders信息
     * @param idVO    接口参数
     * @return 操作结果
     */
    @Override
    @Transactional(rollbackFor = BusinessException.class)
    public Wrapper<Void> deleteMemberStore(HttpHeaders headers, CommonIdVO idVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);

        MemberStoreDO memberStoreDO = memberStoreRepository.findById(idVO.getId()).orElse(null);
        if (memberStoreDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_STORE_DOES_NOT_EXIST);
        }

        memberOrganizationRepository.deleteByMemberIdAndStoreId(loginUser.getMemberId(), memberStoreDO.getId());

        memberStoreRepository.deleteById(idVO.getId());

        //向mq发送删除物流服务收发货地址消息
        logisticsMessageQueueService.deleteLogisticsAddress(memberStoreDO, loginUser);

        return Wrapper.success();
    }

    /**
     * 启用/停用门店
     * @param headers HttpHeaders信息
     * @param idVO    接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<Void> enableMemberStore(HttpHeaders headers, CommonIdVO idVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);

        MemberStoreDO memberStoreDO = memberStoreRepository.findById(idVO.getId()).orElse(null);
        if (memberStoreDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_STORE_DOES_NOT_EXIST);
        }

        memberStoreDO.setStatus(memberStoreDO.getStatus().equals(EnableDisableStatus.ENABLE.getCode()) ? EnableDisableStatus.DISABLE.getCode() : EnableDisableStatus.ENABLE.getCode());

        memberStoreRepository.saveAndFlush(memberStoreDO);

        //向mq发送修改物流服务收发货地址状态消息
        logisticsMessageQueueService.updateLogisticsAddressStatus(memberStoreDO, loginUser);

        return Wrapper.success();
    }
}
